// node fs模块
const fs = require('fs');
// node path模块
const path = require('path');
const RootDir = './src';
// const RootDir = '../../../../src';
const ModulesDir = path.join(RootDir, 'uni_modules');
const FuncDir = path.join('uniCloud', 'cloudfunctions');
const {
	indexContent,
	configContent,
	authContent,
	initContent,
	permissionContent,
	getControllerContent,
	getEntityContent,
	getServiceContent,
	getTableContent,
} = require('./template.js');
// 收集所有的文件路径
const fileDisplay = () => {
	const params = {
		afterend: [],
		frontend: [],
	};
	return new Promise((resolve) => {
		try {
			const filePath = path.resolve(ModulesDir);
			//根据文件路径读取文件，返回文件列表
			const files = fs.readdirSync(filePath);
			//遍历读取到的文件列表
			files.forEach((filename) => {
				//获取当前文件的绝对路径
				const fileDir = path.join(filePath, filename);
				//根据文件路径获取文件信息，返回一个fs.Stats对象
				const stats = fs.statSync(fileDir);
				// 是否是文件夹
				const isDir = stats.isDirectory();
				// 如果是文件夹
				if (isDir) {
					// 云函数文件夹路径
					const funcPath = path.join(fileDir, FuncDir);
					// 如果云函数文件夹存在
					if (filename.startsWith('dx-func') && fs.existsSync(funcPath)) {
						const funcFiles = fs.readdirSync(funcPath);
						funcFiles.map((funcFilename) => {
							if (funcFilename !== 'common') {
								const funcFileDir = path.join(funcPath, funcFilename);
								const funcStats = fs.statSync(funcFileDir);
								const funcIsDir = funcStats.isDirectory();
								let database = [];
								// 读取database的文件
								const databasePath = path.join(fileDir, 'uniCloud', 'database');
								const databaseFiles = fs.readdirSync(databasePath);
								databaseFiles.map((databaseFilename) => {
									if (databaseFilename.includes('schema')) {
										database.push(databaseFilename.split('.').shift());
									}
								});
								if (funcIsDir) {
									params.afterend.push({
										label: funcFilename,
										value: path.join(funcPath, funcFilename),
										database,
									});
								}
							}
						});
					} else if (!['qiun-data-charts'].includes(filename) && filename.startsWith('dx-admin')) {
						params.frontend.push({
							label: filename,
							value: fileDir,
						});
					}
				}
			});
			resolve(params);
		} catch (error) {
			resolve(error.message);
		}
	});
};

const getDatabase = (data) => {
	return new Promise((resolve) => {
		const { funcPath, tableName } = JSON.parse(data);
		const databasePath = path.join(funcPath.split('cloudfunctions').shift(), 'database');
		try {
			//根据文件路径读取文件，返回文件列表
			const files = fs.readdirSync(databasePath);
			//遍历读取到的文件列表
			const tablePath = files.find((filename) => filename === `${tableName}.schema.json`);
			if (tablePath) {
				const tableFileDir = path.join(databasePath, tablePath);
				const tableContent = fs.readFileSync(tableFileDir, 'utf-8').replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g) => (g ? '' : m));
				resolve(JSON.parse(tableContent));
			} else {
				resolve('未找到该表');
			}
		} catch (error) {
			resolve(error.message);
		}
	});
};

// 应用文件夹是否存在，不存在创建
const createDir = (dir) => {
	return new Promise((resolve) => {
		try {
			if (!fs.existsSync(dir)) {
				fs.mkdirSync(dir);
			}
			resolve(true);
		} catch (error) {
			console.log('创建应用文件失败：',error.message);
			resolve(error.message);
		}
	});
};

// 入口文件校验
const checkIndex = (dir) => {
	return new Promise((resolve) => {
		try {
			const indexFile = path.join(dir, 'index.js');
			if (fs.existsSync(indexFile)) {
				// 替换入口文件
				const oldContent = fs.readFileSync(indexFile, 'utf-8');
				if (!oldContent.includes('dx-router-admin')) {
					fs.writeFileSync(indexFile, indexContent);
				}
			} else {
				// 创建入口文件
				fs.writeFileSync(indexFile, indexContent);
			}
			resolve(true);
		} catch (error) {
			console.log('创建入口文件失败：',error.message);
			resolve(error.message);
		}
	});
};

// 配置文件校验
const checkConfig = (dir) => {
	return new Promise((resolve) => {
		try {
			const configFile = path.join(dir, 'config.js');
			if (!fs.existsSync(configFile)) {
				// 创建配置文件
				fs.writeFileSync(configFile, configContent);
			}
			resolve(true);
		} catch (error) {
			console.log('创建配置文件失败：',error.message);
			resolve(error.message);
		}
	});
};

// 中间件文件校验
const checkMiddleware = (dir) => {
	return new Promise((resolve) => {
		try {
			const authFile = path.join(dir, 'auth.js');
			if (!fs.existsSync(authFile)) {
				// 创建auth文件
				fs.writeFileSync(authFile, authContent);
			}
			const initFile = path.join(dir, 'init.js');
			if (!fs.existsSync(initFile)) {
				// 创建init文件
				fs.writeFileSync(initFile, initContent);
			}
			const permissionFile = path.join(dir, 'permission.js');
			if (!fs.existsSync(permissionFile)) {
				// 创建permission文件
				fs.writeFileSync(permissionFile, permissionContent);
			}
			resolve(true);
		} catch (error) {
			console.log('创建中间件文件失败：',error.message);
			resolve(error.message);
		}
	});
};
// pages.json
const checkPagesJson = (frontendModule, fileName, menuName) => {
	return new Promise((resolve) => {
		try {
			const pagesJsonFile = path.join(RootDir, 'pages.json');
			if (fs.existsSync(pagesJsonFile)) {
				const pagesJsonContent = fs
					.readFileSync(pagesJsonFile, 'utf-8')
					.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g) => (g ? '' : m));
				const pagesJson = JSON.parse(pagesJsonContent);
				const subPackages = pagesJson.subPackages;
				if (!subPackages || !subPackages.length) {
					pagesJson.subPackages = [
						{
							root: `uni_modules/${frontendModule}`,
							pages: [
								{
									path: `pages/${fileName}/${fileName}`,
									style: {
										navigationBarTitleText: menuName || fileName,
									},
								},
							],
						},
					];
					fs.writeFileSync(pagesJsonFile, JSON.stringify(pagesJson, null, '\t'));
				} else {
					const pages = subPackages.find((item) => item.root === `uni_modules/${frontendModule}`);
					if (!!pages && pages.pages !== void 0 && Array.isArray(pages.pages)) {
						// 是否已经存在
						const isExist = pages.pages.find((item) => item.path === `pages/${fileName}/${fileName}`);
						if (!isExist) {
							pages.pages.push({
								path: `pages/${fileName}/${fileName}`,
								style: {
									navigationBarTitleText: menuName || fileName,
								},
							});
							fs.writeFileSync(pagesJsonFile, JSON.stringify(pagesJson, null, '\t'));
						}
					} else {
						pagesJson.subPackages.push({
							root: `uni_modules/${frontendModule}`,
							pages: [
								{
									path: `pages/${fileName}/${fileName}`,
									style: {
										navigationBarTitleText: menuName || fileName,
									},
								},
							],
						});
						fs.writeFileSync(pagesJsonFile, JSON.stringify(pagesJson, null, '\t'));
					}
				}
			}
			resolve(true);
		} catch (error) {
			console.log(error);
			resolve(error.message);
		}
	});
};

//生成crud文件
const createCrud = (data) => {
	return new Promise(async (resolve) => {
		const { functionPath, fileName, funcName, frontendModule, tableName, frontendPath, menuName, isCover, isMultiModule, moduleName, params } =
			JSON.parse(data);
		// 应用目录
		const appDir = path.join(functionPath, 'application');
		// 创建应用目录
		let status = await createDir(appDir);
		if (status !== true) {
			resolve('创建应用目录失败');
		}
		// 创建中间件目录
		const middlewareDir = path.join(functionPath, 'middleware');
		status = await createDir(middlewareDir);
		if (status !== true) {
			resolve('创建中间件目录失败');
		}
		let controllerDir = '',
			serviceDir = '';
		// 是否是多模块
		if (isMultiModule) {
			if (!moduleName) {
				resolve('模块名称不能为空');
			}
			// 模块目录
			const moduleDir = path.join(functionPath, 'application', moduleName);
			// 创建模块目录
			status = await createDir(moduleDir);
			if (status !== true) {
				resolve('创建模块目录失败');
			}
			controllerDir = path.join(moduleDir, 'controller');
			serviceDir = path.join(moduleDir, 'service');
		} else {
			controllerDir = path.join(functionPath, 'application', 'controller');
			serviceDir = path.join(functionPath, 'application', 'service');
		}
		// 创建控制器目录
		status = await createDir(controllerDir);
		if (status !== true) {
			resolve('创建控制器目录失败');
		}
		// 创建服务目录
		status = await createDir(serviceDir);
		if (status !== true) {
			resolve('创建服务目录失败');
		}
		// 创建实体目录
		const entityDir = path.join(functionPath, 'application', 'entity');
		status = await createDir(entityDir);
		if (status !== true) {
			resolve('创建实体目录失败');
		}
		//口入文件校验
		status = await checkIndex(functionPath);
		if (status !== true) {
			resolve('入口文件校验失败');
		}
		// 配置文件校验
		status = await checkConfig(functionPath);
		if (status !== true) {
			resolve('配置文件校验失败');
		}
		// 中间件文件校验
		status = await checkMiddleware(middlewareDir);
		if (status !== true) {
			resolve('中间件文件校验失败');
		}
		// 创建控制器文件
		const controllerFile = path.join(controllerDir, `${fileName}.js`);
		const controllerContent = getControllerContent(fileName, params);
		if (fs.existsSync(controllerFile)) {
			if (isCover) {
				// 覆盖
				fs.writeFileSync(controllerFile, controllerContent);
			} else {
				resolve('控制器文件已存在');
			}
		} else {
			// 创建控制器文件
			fs.writeFileSync(controllerFile, controllerContent);
		}
		// 创建实体文件
		const entityFile = path.join(entityDir, `${fileName}.js`);
		const entityContent = getEntityContent(tableName, params);
		if (fs.existsSync(entityFile)) {
			if (isCover) {
				// 覆盖
				fs.writeFileSync(entityFile, entityContent);
			} else {
				resolve('实体文件已存在');
			}
		} else {
			// 创建实体文件
			fs.writeFileSync(entityFile, entityContent);
		}
		// 创建服务文件
		const serviceFile = path.join(serviceDir, `${fileName}.js`);
		const serviceContent = getServiceContent(fileName, isMultiModule);
		if (fs.existsSync(serviceFile)) {
			if (isCover) {
				// 覆盖
				fs.writeFileSync(serviceFile, serviceContent);
			} else {
				resolve('服务文件已存在');
			}
		} else {
			// 创建服务文件
			fs.writeFileSync(serviceFile, serviceContent);
		}
		// 前端目录
		const pagesDir = path.join(frontendPath, 'pages');
		// 创建前端目录
		status = await createDir(pagesDir);
		if (status !== true) {
			resolve('创建前端目录失败');
		}
		// 创建页面目录
		const pageDir = path.join(pagesDir, fileName);
		status = await createDir(pageDir);
		if (status !== true) {
			resolve('创建页面目录失败');
		}
		// 创建前端文件
		const webVueFile = path.join(pageDir, `${fileName}.vue`);
		const webVueContent = getTableContent(fileName, funcName, menuName, isMultiModule, moduleName, params);
		if (fs.existsSync(webVueFile)) {
			if (isCover) {
				// 覆盖
				fs.writeFileSync(webVueFile, webVueContent);
			} else {
				resolve('前端文件已存在');
			}
		} else {
			// 创建前端文件
			fs.writeFileSync(webVueFile, webVueContent);
		}
		// 更新pages.json
		status = await checkPagesJson(frontendModule, fileName, menuName);
		if (status !== true) {
			resolve(status);
		}
		resolve('success');
	});
};

module.exports = {
	fileDisplay,
	createCrud,
	getDatabase,
};
